package state

import (
	"sort"
	"sync"
	"sync/atomic"
)

type StatusStruct struct {
	aliveConn  int64
	mu         sync.Mutex
	connsInfo  map[string]int64
	slavewscon map[string]*SlaveConn
}

func NewState() *StatusStruct {
	return &StatusStruct{
		connsInfo:  map[string]int64{},
		slavewscon: map[string]*SlaveConn{},
	}
}

func (slf *StatusStruct) UpdateALiveConn(n int64) {
	atomic.AddInt64(&slf.aliveConn, n)
}

func (slf *StatusStruct) GetALiveConn() int64 {
	return atomic.LoadInt64(&slf.aliveConn)
}

func (slf *StatusStruct) UpdateConnsInfo(addr string, n int64) {
	slf.mu.Lock()
	defer slf.mu.Unlock()
	slf.connsInfo[addr] += n
	if slf.connsInfo[addr] == 0 {
		delete(slf.connsInfo, addr)
	}
}

func (slf *StatusStruct) ProxyConnsInfo() map[string]int64 {
	slf.mu.Lock()
	defer slf.mu.Unlock()
	r := map[string]int64{}

	for k, v := range slf.connsInfo {
		r[k] = v
	}
	return r
}

func (slf *StatusStruct) InsertSlaveConn(addr string, sc *SlaveConn) {
	slf.mu.Lock()
	defer slf.mu.Unlock()

	slf.slavewscon[addr] = sc
}

func (slf *StatusStruct) DeleteSlaveConn(addr string) {
	slf.mu.Lock()
	defer slf.mu.Unlock()

	delete(slf.slavewscon, addr)
}

func (slf *StatusStruct) SlaveConnsInfo() []*SlaveConn {
	slf.mu.Lock()
	defer slf.mu.Unlock()
	r := []*SlaveConn{}

	for _, v := range slf.slavewscon {
		r = append(r, v)
	}

	sort.SliceStable(r, func(i, j int) bool {
		return r[i].Begin.Unix() > r[j].Begin.Unix()
	})

	return r
}
